package com.wangdao.wechatmall.typehandler;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 类型转换器
 * 当JavaType和JdbcType不匹配的时候
 * 输出映射：数据库varchar → String → Integer[]
 * 输入映射：Integer[] → String → varchar
 * 综上所述 需要一个类型转换  String ←→ Integer[]
 *
 * @author ZhangXiao on 2021/7/5
 */
@MappedTypes(Integer[].class)//映射的Java类型
@MappedJdbcTypes(JdbcType.VARCHAR)//映射的jdbc类型
public class IntegerArrayTypeHandler implements TypeHandler<Integer[]> {

    //Json工具类作为转换的媒介
    ObjectMapper objectMapper = new ObjectMapper();


    //输入映射 Integer[] → String
    //index:输入映射的过程中，预编译，占位符的顺序
    @SneakyThrows
    @Override
    public void setParameter(PreparedStatement preparedStatement, int index, Integer[] integers, JdbcType jdbcType) throws SQLException {
        String value = objectMapper.writeValueAsString(integers);
        preparedStatement.setString(index, value);

    }

    //输出映射 String → Integer[]
    //columnName 查询结果的列名
    //index 查询结果的序号
    @Override
    public Integer[] getResult(ResultSet resultSet, String columnName) throws SQLException {
        String result = resultSet.getString(columnName);
        return transfer(result);
    }

    @Override
    public Integer[] getResult(ResultSet resultSet, int index) throws SQLException {
        String result = resultSet.getString(index);
        return transfer(result);
    }

    @Override
    public Integer[] getResult(CallableStatement callableStatement, int index) throws SQLException {
        String result = callableStatement.getString(index);
        return transfer(result);
    }

    @SneakyThrows
    private Integer[] transfer(String result) {
        Integer[] integers;
        try {
            integers = objectMapper.readValue(result, Integer[].class);
        }catch (JsonProcessingException e){
            return transfer(result);
        }
        return integers;
    }
}
